home *** CD-ROM | disk | FTP | other *** search
- // ThinkMore.m
- //
- // Contains additional methods used in the Thinker class.
- //
- // You may freely copy, distribute, and reuse the code in this example.
- // NeXT disclaims any warranty of any kind, expressed or implied, as to its
- // fitness for any particular use.
-
- #import "Thinker.h"
- #import "SpaceView.h"
- #import "BackView.h"
- #import "SleepView.h"
- #import "BlackView.h"
- #import "Password.h"
- #import "psfuncts.h"
-
-
- #import <appkit/appkit.h>
- #import <objc/NXBundle.h>
-
-
- #define VIEWDIRECTORY "/LocalLibrary/BackSpaceViews"
-
- static char *compiledViewNames[] = {
- "Space",
- "Boink",
- "Black",
- };
-
- #define COMVIEWCOUNT (sizeof(compiledViewNames)/sizeof(*compiledViewNames))
-
- @implementation Thinker(thinkMore)
-
-
- //must invoke this before creating window or setting up the views
- - getViewType
- {
- int i;
- id theMatrix;
- char buf[MAXPATHLEN];
- ModuleInfo *m;
-
- strcpy( buf, NXHomeDirectory());
- strcat( buf, "/Library/BackSpaceViews");
-
- moduleList = [[ModuleList alloc] init];
-
- [self loadViewsFrom:buf];
- [self loadViewsFrom: [self appDirectory]];
- [self loadViewsFrom: VIEWDIRECTORY];
-
- for (i = 0; i < COMVIEWCOUNT; i++)
- {
- m = [[ModuleInfo alloc]
- initWithView:nil name:compiledViewNames[i] path:NULL];
- [moduleList addObject: m];
- }
-
- [moduleList sort];
- [viewSelectionBrowser loadColumnZero];
- theMatrix = [viewSelectionBrowser matrixInColumn:0];
- [theMatrix selectCellAt:realViewIndex :0];
- [theMatrix scrollCellToVisible:realViewIndex :0];
-
- return self;
- }
-
-
- - selectRealViewIndex:sender
- {
- //sender is the NXBrowser
- int index = [[viewSelectionBrowser matrixInColumn:0] selectedRow];
-
- if (index == realViewIndex) return self;
- if (index == -1)
- {
- id theMatrix = [viewSelectionBrowser matrixInColumn:0];
- [theMatrix selectCellAt:realViewIndex :0];
- [theMatrix scrollCellToVisible:realViewIndex :0];
- return self;
- }
-
- realViewIndex = index;
- [self setVirtualViewIndexAndIncrement:NO];
-
- return self;
- }
-
-
- // this method is the actual view setting mechanism,
- // guaranteed to get called to set the view
-
- - setVirtualViewIndexAndIncrement:(BOOL)flag
- {
- id myView;
- id newInspector;
-
- if (realViewIndex)
- {
- virtualViewIndex = realViewIndex-1;
- [self selectScreenSaverViews];
- }
-
- else
- {
- if (flag)
- {
- virtualViewIndex = random() % [moduleList count];
- [self selectScreenSaverViews];
- myView = [self backView];
-
- while ([myView respondsTo:@selector(isBoringScreenSaver)]
- && [myView isBoringScreenSaver])
- {
- if (++virtualViewIndex >= [moduleList count])
- virtualViewIndex = 0;
-
- [self selectScreenSaverViews];
- myView = [self backView];
- }
- }
- else [self selectScreenSaverViews];
- }
-
-
- //---------------------------------------------
- // now plug in the inspector
- //---------------------------------------------
- myView = [self backView];
-
- if ([myView respondsTo:@selector(inspector:)])
- {
- newInspector = [myView inspector:self];
- if (!newInspector) newInspector = [self nullInspector];
- }
- else newInspector = [self nullInspector];
-
- if (newInspector != currentInspector)
- {
- if ([oldInspectorOwner respondsTo:@selector(inspectorWillBeRemoved)])
- [oldInspectorOwner inspectorWillBeRemoved];
- // either myView will be the inspector owner, or it won't care
- oldInspectorOwner = myView;
-
- // don't want it to resize the box. Suboptimal technique...
- [newInspector setFrame:&inspectorFrame];
-
- [invisibleInspectorBox setContentView: newInspector];
- currentInspector = newInspector;
-
- if ([myView respondsTo:@selector(inspectorInstalled)])
- [myView inspectorInstalled];
-
- [invisibleInspectorBox display];
- }
-
- return self;
- }
-
-
- - selectScreenSaverViews
- {
- id theView, bigWindow;
- int myBacking;
-
- //need to order out big window if that's the type and buffering changed
-
- theView = [self backView];
-
- myBacking = [self backingTypeForView:theView];
-
- [self createBigWindowIfNecessaryForView:theView];
-
- if (myBacking == NX_BUFFERED) bigWindow = bigBufferedWindow;
- else bigWindow = bigUnbufferedWindow;
-
- if (windowType == BACKWINDOW)
- {
- if (spaceWindow != bigWindow)
- {
- [spaceWindow orderOut:self];
- [self useBackWindow:globalTier];
- }
- }
-
- spaceView = theView;
- [self installSpaceViewIntoWindow:spaceWindow];
-
- if ([spaceView respondsTo:@selector(setImage:)])
- [spaceView setImage: image];
- if ([spaceView respondsTo:@selector(newWindow)]) [spaceView newWindow];
-
- [self setWindowTitle];
-
- NXWriteDefault([NXApp appName], "viewType", (realViewIndex ?
- ([moduleList nameAt: realViewIndex-1]) : "All"));
-
-
- if (windowType)
- {
- // the unbuffered window looks better if you just display
- // its contents, but for a buffered oneshot window, you must
- // display the window to make sure the window server window exists.
-
- if (myBacking == NX_BUFFERED)
- [spaceWindow display];
- else
- {
- [spaceView fillBoundsWithBlack];
- [spaceView display];
- }
- }
-
- if (normalWindow && (windowType == NORMALWINDOW))
- {
- if (myBacking == NX_BUFFERED)
- [normalWindow setBackingType:NX_BUFFERED];
- else[normalWindow setBackingType:NX_RETAINED];
- }
-
- return self;
- }
-
- - setWindowTitle
- {
- if ([spaceView respondsTo:@selector(windowTitle)])
- {
- [normalWindow setTitle: NXLocalString([spaceView windowTitle],0,0)];
- }
- else [normalWindow setTitle: NXLocalString("BackSpace",0,0)];
- return self;
- }
-
-
- - getScreenLockerSetting
- {
- const char *ptr;
-
- [screenLocker setState:0];
-
- ptr = NXGetDefaultValue([NXApp appName], "screenLocker");
-
- if (!ptr || !strcmp(ptr,"Off")) [self setScreenLocker:NO andRemember:NO];
- else [self setScreenLocker:YES andRemember:NO];
-
- return self;
- }
-
- - changeScreenLockerSetting:sender
- {
- if (![password checkPassword:
- NXLocalString("Enter password to change screen lock setting:",0,0)
- randomPos:NO checkLock:NO withView:nil])
- {
- [screenLocker setState:[password isLocked]];
- return self;
- }
-
- if (![password validPassword] && ![password setPassword:self])
- {
- [screenLocker setState:[password isLocked]];
- return self;
- }
-
- [self setScreenLocker:([screenLocker state])andRemember:YES];
- return self;
- }
-
- - setScreenLocker:(BOOL)val andRemember:(BOOL)rem
- {
- [screenLocker setState:val];
- [password setLock: val];
-
- if (rem)
- {
- if (val) NXWriteDefault([NXApp appName], "screenLocker", "On");
- else NXRemoveDefault([NXApp appName], "screenLocker");
- }
-
- return self;
- }
-
-
-
-
- //---------------------------------------------------
- // View manager routines
- //---------------------------------------------------
-
- - backView
- {
- NXRect aFrame = {{0,0},{200,200}};
- id theView;
-
- if (![moduleList viewAt:virtualViewIndex])
- {
- char path[MAXPATHLEN];
- id myClass;
- const char *name;
- char *filenames[] = {path, NULL};
- ModuleInfo *mp;
- struct mach_header *header;
-
- mp = [moduleList objectAt: virtualViewIndex];
- name = [mp viewName];
-
- // before I loaded all classes at launch time; now classes are
- // loaded only as needed. This idea and some of the code here is
- // from bill bumgarner, thanx!
-
- if ([mp path]) // we have path but no instance, must load class
- {
- long ret;
- do
- {
- sprintf(path, "%s/%sView.BackO", [mp path], name);
- ret = objc_loadModules(filenames, NULL, NULL, &header, NULL);
-
- // objc_loadModules succeeds with a warning if the architecture of the
- // object file is wrong, so we better check if we really got a class
-
- if (!ret) // load succeeded or was wrong architecture
- {
- sprintf(path,"%sView", name);
- myClass = objc_getClass(path);
- if (!myClass) ret = -1;
- }
-
- } while (ret && [mp useNextPath]);
-
- [mp discardAltPaths];
-
- if (ret)
- {
- // Ugh, failed. Will instantiate a BlackView instead...
- NXRunAlertPanel([NXApp appName], NXLocalString(
- "Could not dynamically load class: %sView",0,0),
- NULL, NULL, NULL, name);
- name = "Black";
- }
- else
- {
- [mp setHeader:header];
- }
- }
-
- //at this point we must have a valid name for a loaded class
-
- sprintf(path,"%sView", name);
- myClass = objc_getClass(path);
-
- theView = [[myClass allocFromZone:backZone] initFrame:&aFrame];
- [[moduleList objectAt:virtualViewIndex] setView:theView];
- }
-
- theView = [moduleList viewAt:virtualViewIndex];
-
- return theView;
- }
-
- - showInfoPanel:sender
- {
- if (!infoPanel)
- {
- if (![NXApp loadNibSection:"Info.nib" owner:self withNames:NO fromZone:[self zone]])
- NXLogError ("Can't find Info.nib!");
- }
- [infoPanel makeKeyAndOrderFront:sender];
- return self;
- }
-
- #define SLEEPSIZE (3.0)
-
- - createSleepWindow
- {
- if (!sleepWindow)
- {
- NXRect sleep={{0, 0},{SLEEPSIZE, SLEEPSIZE}};
- id aView = [[SleepView alloc] initFrame:&sleep];
-
- sleepWindow = [[Window alloc]
- initContent:&sleep style:NX_TOKENSTYLE
- backing:NX_NONRETAINED buttonMask:0 defer:NO];
-
- [sleepWindow setEventMask:(NX_MOUSEENTEREDMASK | NX_MOUSEEXITEDMASK)];
- PSsetwindowlevel(SLEEPTIER, [sleepWindow windowNum]);
- PSWmakeWindowGray([sleepWindow windowNum]);
- [[sleepWindow setContentView: aView] free];
-
- [sleepWindow setTrackingRect:&sleep inside:YES owner:aView
- tag:3 left:NO right:NO];
- }
-
- return self;
- }
-
- - setSleepCorner:(int)val
- {
- NXRect screen={{0, 0}};
- NXCoord x = 0.0, y = 0.0;
-
- if (val)
- {
- [NXApp getScreenSize:&(screen.size)];
- [self createSleepWindow];
- if (val == 2 || val == 3) x = screen.size.width - SLEEPSIZE;
- if (val == 3 || val == 4) y = screen.size.height - SLEEPSIZE;
- [sleepWindow moveTo:x :y];
- [sleepWindow orderFront:self];
- }
- else [sleepWindow orderOut:self];
- return self;
- }
-
- - getHotCornerSetting
- {
- const char *ptr;
- int tval, val=0;
-
- ptr = NXGetDefaultValue([NXApp appName], "hotCorner");
- if (ptr)
- {
- sscanf(ptr,"%d",&tval);
- if (tval >= 0 && tval <= 4) val = tval;
- }
-
- [cornerView setState:val];
- [self setSleepCorner:val];
-
- return self;
- }
-
-
- @end
-